﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Caching;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition;
using System.Collections;
using System.Globalization;

namespace Steve.UI.Extensions
{
    [Export(typeof(ICacheService))]
    [PartCreationPolicy(CreationPolicy.Shared)]
    public sealed class HttpContextCacheService : ICacheService
    {
        [Import]
        public IHttpContextBaseBuilder ContextBuilder { get; set; }

        private static string CreateKey(CacheType cacheType, string cacheKey)
        {
            return string.Format(CultureInfo.InvariantCulture, "{0:f}_{1}", cacheType, cacheKey);
        }

        public T GetValue<T>(CacheType cacheType, string cacheKey) where T : class
        {
            return (T)ContextBuilder.BuildCurrent().Cache.Get(CreateKey(cacheType, cacheKey));
        }

        public void PutValue(CacheType cacheType, string cacheKey, object value, TimeSpan? ttl)
        {
            ContextBuilder.BuildCurrent().Cache.Insert(CreateKey(cacheType, cacheKey), value, null, Cache.NoAbsoluteExpiration, ttl == null ? Cache.NoSlidingExpiration : ttl.Value);
        }

        public void Invalidate(CacheType cacheType, string cacheKey)
        {
            ContextBuilder.BuildCurrent().Cache.Remove(CreateKey(cacheType, cacheKey));
        }

        public void Invalidate(CacheType cacheType)
        {
            var cache = ContextBuilder.BuildCurrent().Cache;
            var prefix = CreateKey(cacheType, string.Empty);
            var query = from kvp in cache.OfType<DictionaryEntry>()
                               let stringKey = kvp.Key as string
                               where stringKey != null && stringKey.StartsWith(prefix, StringComparison.Ordinal)
                               select stringKey;

            var keysToRemove = query.ToList();

            foreach (var key in keysToRemove)
            {
                cache.Remove(key);
            }
        }

        public IEnumerable<string> GetKeys(CacheType cacheType)
        {
            throw new NotImplementedException();
        }
    }
}
